import {
  IBaseData,
  IData,
  IFieldData,
  IShapeData,
  IStreamlineData,
} from '@amcax/base';
import { Vector3Tuple } from 'three-legacy';
import { ENTITY_TYPE } from '../../types';

/**
 * 网格数据格式
 */
interface IMeshData extends IBaseData {
  /**
   * 模型的点二维数组，比如： [[0, 0, 0], [1, 1, 1], [2, 2, 2]]
   */
  points: Vector3Tuple[];
  /**
   * 模型的三角面片二维数组，值是points index；比如： [[0, 1, 2], [3, 4, 5]]
   */
  facets: Vector3Tuple[];
  /**
   * 零维网格，键值对（id: points index）；比如：质量点 {"1": 0, "2": 1, "3":2, "4":3}
   */
  d0: Map<string, number>;
  /**
   * 一维网格，键值对（id: points index数组）；比如：线 {"5": [0,1], "6": [1,2], "7": [2,3]}
   */
  d1: Map<string, number[]>;
  /**
   * 二维网格，键值对（id: facets index数组）；比如：{
   *  "8": [0], "9": [1], "10": [2], // 三角形
   *  "11": [0, 1]  // 四边形
   * }
   */
  d2: Map<string, number[]>;
  /**
   * 三维网格，键值对（id: facets index数组）；比如：{
   * "12": [0, 1, 2, 3], // 四面体
   *   "13": [0, 1, [2, 3], [4, 5], [6, 7]], // 三棱柱，混合结构，目的是来渲染网格的线框
   *                                         // 其中数组（四边形）的线框就是将facet的点按顺序连接
   * }
   */
  d3: Map<string, number[]>;
}

interface IPostprocessData {
  extra: { min: number; max: number };
  meshes?: IShapeData[];
  fields?: IFieldData[];
  curves?: IStreamlineData[];
}

function isIPostprocessData(
  data: IData[] | IPostprocessData,
): data is IPostprocessData {
  if (!data) {
    return false;
  }
  return 'fields' in data || 'meshes' in data;
}

/**
 * 拓扑结构
 */
interface ITopologyStruct {
  type: ENTITY_TYPE;
  index: string;
  children: ITopologyStruct[];
}

/**
 * 模型事件类型
 */
enum ModelEventType {
  /**
   * 选取 Entity
   */
  Pick = 'ModelPick',
  /**
   *  设置当前选取模式
   */
  SetCurrentPickType = 'ModelSetCurrentPickType',
  /**
   * 切换主题
   */
  SwitchTheme = 'ModelSwitchTheme',
  /**
   *  设置Entity支持选取类型列表
   */
  PickTypes = 'ModelPickTypes',
  /**
   * 从 form表单来设置选中项
   */
  SetPicked = 'ModelSetPicked',
  /**
   * 清空选中
   */
  Clear = 'ModelClear',
  /**
   * 加载模型
   */
  Loading = 'ModelLoading',
  /**
   * 加载完成
   */
  Loaded = 'ModelLoaded',
  /**
   * Clipping 模型切面事件
   */
  ClippingChange = 'ModelClippingChange',
  /**
   * 加载场等相关数据
   */
  LoadingField = 'ModelLoadingField',
  /**
   * 设置colormap
   */
  SetColormap = 'ModelSetColormap',
  /**
   * 模型的扩展数据，比如：场的最大最小值
   */
  SetExtra = 'ModelSetExtra',
  /**
   * 重置colorbar，包括colormap、extra的值
   */
  ResetColorbar = 'ModelResetColorbar',

  /**
   * 记录网格数据
   */
  MeshesData = 'MeshesData',
}

interface ModelEvent {}

/**
 * 模型Entity选取事件
 */
interface ModelPickEvent extends ModelEvent {
  indices: string[]; // id 数组 全量更新，不在里面的都取消选中
  selected: boolean; // 是否选中
  theme?: ModelTheme; // 主题
}

/**
 * 切换模型Entity选取类型事件
 */
interface ModelPickSwitchEvent extends ModelEvent {
  type: ENTITY_TYPE;
  clear?: boolean; // 是否清空旧的选中
}

/**
 * 设置模型Entity可选取类型列表事件
 */
interface ModelPickTypesEvent extends ModelEvent {
  types: ENTITY_TYPE[];
  mix?: boolean; // 是否是混合模式
}

/**
 *  从 form表单来设置选中项，根据不同的theme
 */
interface ModelSetPickedEvent extends ModelPickEvent {
  theme: ModelTheme;
}

/**
 * clipping 模型切面
 */
interface ModelClippingChangeEvent extends ModelEvent {
  c: number;
  x: number;
  y: number;
  z: number;
}

enum ModelTheme {
  Default,
  Source,
  Target,
}

enum MeshType {
  Points = 'Points',
  Line = 'Line',
  Face = 'Face',
  FaceWireframe = 'FaceWireframe',
}

/**
 * 模型显示类型，几何、网格、仿真、后处理
 */
enum VisualType {
  Geometry = 'geometry',
  ResultMesh = 'resultMesh',
  Simulation = 'simulation',
  Visualization = 'visualization',
  MeshQuality = 'meshQuality', // 网格质量渲染（新的网格数据格式）
}

interface ILoadRequest {
  uuid: string;
  params?: any;
}

interface ILoadParams {
  type: VisualType | null;
  data: ILoadRequest | null;
}

/**
 * shape的信息，包括顶点数、边数、面数
 */
interface IShapeInfo {
  vertexCount: number;
  edgeCount: number;
  faceCount: number;
}

// 几何简化事件类型
enum TopoEvents {
  SHOW_TOPO_DIALOG = 'SHOW_TOPO_DIALOG',
  HIDE_TOPO_DIALOG = 'HIDE_TOPO_DIALOG',
}

export {
  isIPostprocessData,
  MeshType,
  ModelEventType,
  ModelTheme,
  TopoEvents,
  VisualType,
};
export type {
  ILoadParams,
  ILoadRequest,
  IMeshData,
  IPostprocessData,
  IShapeInfo,
  ITopologyStruct,
  ModelClippingChangeEvent,
  ModelPickEvent,
  ModelPickSwitchEvent,
  ModelPickTypesEvent,
  ModelSetPickedEvent,
};
